package com.hsc.db.tools;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;

import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Header;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.util.ByteArrayDataSource;
import javax.mail.util.SharedByteArrayInputStream;

import com.sun.mail.util.BASE64DecoderStream;
import com.sun.mail.util.QPDecoderStream;

import android.content.Context;
import android.os.Environment;
import android.util.Base64;

public class ReciveOneMail {



	private MimeMessage mimeMessage = null;

	private String saveAttachPath = ""; // 附件下载后的存放目录

	private StringBuffer bodytext = new StringBuffer();// 存放邮件内容

	private String dateformat = "yy-MM-dd HH:mm"; // 默认的日前显示格式
	private String type="";
	private String fname="";
	private ArrayList<String> arrfilelist;


	public ArrayList<String> getArrfilelist() {
		return arrfilelist;
	}



	public void setArrfilelist(ArrayList<String> arrfilelist) {
		this.arrfilelist = arrfilelist;
	}



	public ReciveOneMail(MimeMessage mimeMessage) {

		this.mimeMessage = mimeMessage;
		arrfilelist = new ArrayList<String>();

	}



	public void setMimeMessage(MimeMessage mimeMessage) {

		this.mimeMessage = mimeMessage;

	}



	/**

	 * 获得发件人的地址和姓名

	 */

	public String getFrom() {

		try {
			InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();

			String from = address[0].getAddress();

			////System.out.println("from ="+from);
			if (from == null)

				from = "";

			String personal =  address[0].getPersonal();
			////System.out.println("personal="+personal);
			if (personal == null)

				personal = "";
			else
				personal =encodeFormat(address[0].getPersonal());


			String fromaddr ="";
			if(personal.length()>0)
			{
				fromaddr= personal;
			}else
			{
				fromaddr=from;
			}

			return fromaddr;
		}catch(Exception e)
		{
			e.printStackTrace();
		}

		return null;
	}



	/**

	 * 获得邮件的收件人，抄送，和密送的地址和姓名，根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址

	 */



	public String getMailAddress(String type) {

		String mailaddr = "";
		try{


			String addtype = type.toUpperCase();

			InternetAddress[] address = null;

			if (addtype.equals("TO") || addtype.equals("CC")

					|| addtype.equals("BCC")) {

				if (addtype.equals("TO")) {

					address = (InternetAddress[]) mimeMessage

							.getRecipients(Message.RecipientType.TO);


				} else if (addtype.equals("CC")) {

					address = (InternetAddress[]) mimeMessage

							.getRecipients(Message.RecipientType.CC);

				} else {

					address = (InternetAddress[]) mimeMessage

							.getRecipients(Message.RecipientType.BCC);

				}

				if (address != null) {

					for (int i = 0; i < address.length; i++) {

						String email = address[i].getAddress();

						if (email == null)

							email = "";

						else {

							email = MimeUtility.decodeText(email);

						}
						////System.out.println("email="+email);

						String personal = address[i].getPersonal();

						if (personal == null)

							personal = "";

						else {
							personal =encodeFormat(personal);

						}

						////System.out.println("personal="+personal);

						String compositeto="";

						if(personal.length()>0)
						{
							compositeto = personal;
						}else
						{
							compositeto = email;
						}

						mailaddr += "," + compositeto;

					}

					//System.out.println("addr="+mailaddr);
					mailaddr = mailaddr.substring(1);

					//System.out.println("addr="+mailaddr);
					return mailaddr;

				}

			} else {

				throw new Exception("Error emailaddr type!");

			}

		}catch(Exception e)
		{
			e.printStackTrace();
		}

		return mailaddr;

	}



	/**

	 * 获得邮件主题

	 */

	public String getSubject() {

		String subject = "";
		try {

			String sub = mimeMessage.getSubject();
//		        String[] header = mimeMessage.getHeader("CC");
//		        System.out.print("--------------"+header[0]);
			String chaset =mimeMessage.getSubject();
			//System.out.println("subject ="+sub);

			if (sub.indexOf("?B?") > 0) {
				if (chaset.indexOf("GBK") > 0 || chaset.indexOf("gbk") > 0
						|| chaset.indexOf("UTF") > 0
						|| chaset.indexOf("utf") > 0) {

					subject = MimeUtility.decodeText(mimeMessage.getSubject());

				} else if (chaset.indexOf("gb18030") > 0) {
					String str = sub.substring(sub.indexOf("?B?") + 3,
							sub.indexOf("?="));
					byte[] t = Base64.decode(str, Base64.DEFAULT);
					subject = new String(t, "gbk");
				}
			} else {
				subject = MimeUtility.decodeText(mimeMessage.getSubject());
			}


			if (subject == null)

				subject = "";

		} catch (Exception exce) {
			exce.printStackTrace();
		}

		return subject;

	}


	/**

	 * 编码转换

	 */

	public String encodeFormat(String val)
	{
		String subject = "";
		String sub =val;

		String chaset = null;

		try {
			chaset = val;

			if (sub.indexOf("?B?") > 0) {
				if (chaset.indexOf("GBK") > 0 || chaset.indexOf("gbk") > 0
						|| chaset.indexOf("UTF") > 0
						|| chaset.indexOf("utf") > 0) {

					subject = MimeUtility.decodeText(val);

				} else if (chaset.indexOf("gb18030") > 0) {
					String str = sub.substring(sub.indexOf("?B?") + 3,
							sub.indexOf("?="));
					byte[] t = Base64.decode(str, Base64.DEFAULT);
					subject = new String(t, "gbk");
				}
			} else {
				subject = MimeUtility.decodeText(val);
			}
		}catch (Exception exce) {
			exce.printStackTrace();
		}


		return subject;
	}

	public String encodeFilename(String val)
	{
		String subject = "";
		String sub =val;

		String chaset = null;

		try {
			chaset = val;

			if(val.indexOf("?B?")>0)
			{

				chaset = val.substring(2,val.indexOf("?B?"));

				String str = sub.substring(sub.indexOf("?B?") + 3,
						sub.indexOf("?="));
				byte[] t = Base64.decode(str, Base64.DEFAULT);
				//System.out.println("chaset="+chaset+"  "+chaset.indexOf("18030"));
				if (chaset.indexOf("18030") > 0)
				{
					subject = new String(t, "gbk");
				}else
				{
					subject = new String(t, chaset);
				}


			}else
			{
				subject = val;
			}



		}catch (Exception exce) {
			exce.printStackTrace();
		}


		return subject;
	}

	/**

	 * 获得邮件发送日期

	 */



	public String getSentDate() {
		try {
			Date sentdate = mimeMessage.getSentDate();

			SimpleDateFormat format = new SimpleDateFormat(dateformat);

			return format.format(sentdate);
		}catch(Exception e)
		{
			e.printStackTrace();
		}

		return null;

	}



	/**

	 * 获得邮件正文内容

	 */

	public String getBodyText() {

		return bodytext.toString();

	}



	/**

	 * 解析邮件，把得到的邮件内容保存到一个StringBuffer对象中，解析邮件 主要是根据MimeType类型的不同执行不同的操作，一步一步的解析

	 */

	public void getMailContent(Part part,Context context) {
		try {
			String contenttype = part.getContentType();
			String[] encoding = part.getHeader("Content-Transfer-Encoding");
			String bianma = "base64";
			if(encoding!=null)
			{
				bianma = encoding[0];
				//System.out.println("encoding="+encoding[0]);
			}


			String charset = "";

			//System.out.println("CONTENTTYPE: " + contenttype);

			if (part.isMimeType("text/plain")) {
				byte[] by = new byte[1024*1024];
				int len =0;
				if(bianma.equals("quoted-printable"))
				{
					QPDecoderStream qp = (QPDecoderStream)part.getContent();
					len = qp.read(by);
				}else if (bianma.equals("base64"))
				{
					BASE64DecoderStream b = (BASE64DecoderStream)part.getContent();
					len = b.read(by);
				}else if(bianma.equals("7bit"))
				{
					SharedByteArrayInputStream b = (SharedByteArrayInputStream)part.getContent();
//    	        		bodytext.append(part.getContent().toString());
//    	        		return;
					len = b.read(by);
				}



				byte[] bye = new byte[len];
				System.arraycopy(by, 0,bye, 0, len);



				if(contenttype.indexOf("UTF")>0||contenttype.indexOf("utf")>0)
				{
					charset ="utf-8";
				}else if(contenttype.indexOf("GBK")>0||contenttype.indexOf("gbk")>0)
				{
					charset ="gbk";
				}else
				{
					charset="us-ascii";
				}
				String val = new String(bye,charset);


				bodytext.append(val);

			}
			else if (part.isMimeType("text/html")) {

				byte[] by = new byte[1024*1024];
				int len =0;
				if(bianma.equals("quoted-printable"))
				{
					QPDecoderStream qp = (QPDecoderStream)part.getContent();
					len = qp.read(by);
				}else if (bianma.equals("base64"))
				{
					BASE64DecoderStream b = (BASE64DecoderStream)part.getContent();
					len = b.read(by);
				}



				byte[] bye = new byte[len];
				System.arraycopy(by, 0,bye, 0, len);



				if(contenttype.indexOf("UTF")>0||contenttype.indexOf("utf")>0)
				{
					charset ="utf-8";
				}else if(contenttype.indexOf("GBK")>0||contenttype.indexOf("gbk")>0)
				{
					charset ="gbk";
				}else
				{
					charset="gbk";
				}
				String val = new String(bye,charset);

				//System.out.println("text/html="+val);
				val = val.replace("cid:","" );
				//System.out.println("text/html_replace="+val);

				bodytext.append(val);

			}
			else if (part.isMimeType("multipart/*")) {

				type = part.getContentType();

				DataSource source = new ByteArrayDataSource(part.getInputStream(), "multipart/*");
				Multipart mp = new MimeMultipart(source);
				int counts = mp.getCount();
				for (int i = 0; i < counts; i++)
				{
					getMailContent(mp.getBodyPart(i),context);
				}

			}
			else if (part.isMimeType("image/*")) {
				String disposition = part.getDisposition();
				//System.out.println("disposition"+disposition);
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String filename = encodeFilename(part.getFileName());
					this.arrfilelist.add(filename);
					//System.out.println("filename ="+filename);
				}else
				{
					String[] ad= part.getHeader("Content-ID");
					this.fname = ad[0].substring(1,ad[0].length()-1);
					BASE64DecoderStream b = (BASE64DecoderStream)part.getContent();

					InputStream inputStream = part.getDataHandler().getDataSource().getInputStream();
					String sdpath =getSDPath()+"/my_email";
					File f = new File(sdpath);

					if(f.exists()!=true)
					{
						f.mkdir();
					}

//    	    	          FileOutputStream out = context.openFileOutput(this.fname, Context.MODE_PRIVATE);
					FileOutputStream out = new FileOutputStream(new File(sdpath+"/"+this.fname));
					int bytesWritten = 0;
					int byteCount = 0;


					byte[] bytes = new byte[1024];
					int by =0;
					while((inputStream.read(bytes)) != -1){
						out.write(bytes);
					}

					inputStream.close();
					out.close();
				}


			} else if(part.isMimeType("application/*")){
				String disposition = part.getDisposition();
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String filename = encodeFilename(part.getFileName());
					this.arrfilelist.add(filename);
					//System.out.println("filename ="+filename);
				}else
				{
					String[] ad= part.getHeader("Content-ID");
					this.fname = ad[0].substring(1,ad[0].length()-1);
					BASE64DecoderStream b = (BASE64DecoderStream)part.getContent();

					InputStream inputStream = part.getDataHandler().getDataSource().getInputStream();

//    	    	          FileOutputStream out = context.openFileOutput(this.fname, Context.MODE_PRIVATE);
					String sdpath =getSDPath()+"/my_email";
					File f = new File(sdpath);

					if(f.exists()!=true)
					{
						f.mkdir();
					}

//    	    	          FileOutputStream out = context.openFileOutput(this.fname, Context.MODE_PRIVATE);
					FileOutputStream out = new FileOutputStream(new File(sdpath+"/"+this.fname));

					int bytesWritten = 0;
					int byteCount = 0;


					byte[] bytes = new byte[1024];
					int by =0;
					while((inputStream.read(bytes)) != -1){
						out.write(bytes);
					}

					inputStream.close();
					out.close();
				}

			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}



	}


	public   void download(Part part,String filename)
	{
		try {
			String contenttype = part.getContentType();
			String[] encoding = part.getHeader("Content-Transfer-Encoding");
			String bianma = "base64";
			if(encoding!=null)
			{
				bianma = encoding[0];
				//System.out.println("encoding="+encoding[0]);
			}

			String charset = "";
			//System.out.println("CONTENTTYPE: " + contenttype);

			if (part.isMimeType("multipart/*")) {

				type = part.getContentType();

				DataSource source = new ByteArrayDataSource(part.getInputStream(), "multipart/*");
				Multipart mp = new MimeMultipart(source);
				int counts = mp.getCount();
				for (int i = 0; i < counts; i++)
				{
					download(mp.getBodyPart(i),filename);
				}

			}

			else if (part.isMimeType("image/*")) {
				String disposition = part.getDisposition();
				//System.out.println("disposition"+disposition);
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String f = encodeFilename(part.getFileName());
					//System.out.println("f="+f+"filename ="+filename);
					if(filename.indexOf(f)>0)
					{
						//System.out.println("f="+f+"filename ="+filename);
						InputStream inputStream = part.getDataHandler().getDataSource().getInputStream();

						FileOutputStream out =new  FileOutputStream(new File(filename));

						int bytesWritten = 0;
						int byteCount = 0;


						byte[] bytes = new byte[1024];
						int by =0;
						while((inputStream.read(bytes)) != -1){
							out.write(bytes);
						}

						inputStream.close();
						out.close();
					}
				}

			}
			else if (part.isMimeType("text/plain")&& contenttype.indexOf("contenttype")<0) {

				String disposition = part.getDisposition();
				//System.out.println("disposition"+disposition);
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String f = encodeFilename(part.getFileName());
					//System.out.println("f="+f+"filename ="+filename);
					if(filename.indexOf(f)>0)
					{
						//System.out.println("f="+f+"filename ="+filename);
						InputStream inputStream = part.getDataHandler().getDataSource().getInputStream();

						FileOutputStream out =new  FileOutputStream(new File(filename));

						int bytesWritten = 0;
						int byteCount = 0;


						byte[] bytes = new byte[1024];
						int by =0;
						while((inputStream.read(bytes)) != -1){
							out.write(bytes);
						}

						inputStream.close();
						out.close();
					}
				}




			}
			else if(part.isMimeType("application/*")){
				String disposition = part.getDisposition();
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String f = encodeFilename(part.getFileName());
					//System.out.println("f="+f+"filename ="+filename);
					if(filename.indexOf(f)>0)
					{
						//System.out.println("f="+f+"filename ="+filename);
						InputStream inputStream = part.getDataHandler().getDataSource().getInputStream();

						FileOutputStream out =new  FileOutputStream(new File(filename));

						int bytesWritten = 0;
						int byteCount = 0;


						byte[] bytes = new byte[1024];
						int by =0;
						while((inputStream.read(bytes)) != -1){
							out.write(bytes);
						}

						inputStream.close();
						out.close();
					}




				}

			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}


	}


	public static  String getSDPath(){
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState()
				.equals(android.os.Environment.MEDIA_MOUNTED);  //判断sd卡是否存在
		if  (sdCardExist)
		{
			sdDir = Environment.getExternalStorageDirectory();//获取跟目录
		}
		return sdDir.toString();

	}

	public void getFujianCount(Part part) {

		try {
			String contenttype = part.getContentType();
			String[] encoding = part.getHeader("Content-Transfer-Encoding");
			String bianma = "base64";
			if(encoding!=null)
			{
				bianma = encoding[0];
				//System.out.println("encoding="+encoding[0]);
			}


			String charset = "";

			//System.out.println("CONTENTTYPE: " + contenttype);

			if (part.isMimeType("text/plain")&& contenttype.indexOf("contenttype")<0) {

				String disposition = part.getDisposition();
				//System.out.println("disposition"+disposition);
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String filename = encodeFilename(part.getFileName());
					this.arrfilelist.add(filename);
					//System.out.println("filename1 ="+filename);
				}



			}
			else if (part.isMimeType("multipart/*")) {

				type = part.getContentType();

				DataSource source = new ByteArrayDataSource(part.getInputStream(), "multipart/*");
				Multipart mp = new MimeMultipart(source);
				int counts = mp.getCount();
				for (int i = 0; i < counts; i++)
				{
					getFujianCount(mp.getBodyPart(i));
				}

			}
			else if (part.isMimeType("image/*")) {
				String disposition = part.getDisposition();
				//System.out.println("disposition"+disposition);
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String filename = encodeFilename(part.getFileName());
					this.arrfilelist.add(filename);
					//System.out.println("filename ="+filename);
				}


			} else if(part.isMimeType("application/*")){
				String disposition = part.getDisposition();
				if(disposition!=null &&(disposition.equals(Part.ATTACHMENT)))
				{
					String filename = encodeFilename(part.getFileName());
					this.arrfilelist.add(filename);
					//System.out.println("filename ="+filename);
				}

			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}


	}



	/**

	 * 判断此邮件是否需要回执，如果需要回执返回"true",否则返回"false"

	 */

	public boolean getReplySign() throws MessagingException {

		boolean replysign = false;

		String needreply[] = mimeMessage

				.getHeader("Disposition-Notification-To");

		if (needreply != null) {

			replysign = true;

		}

		return replysign;

	}



	/**

	 * 获得此邮件的Message-ID

	 */

	public String getMessageId() throws MessagingException {

		return mimeMessage.getMessageID();

	}



	/**

	 * 【判断此邮件是否已读，如果未读返回返回false,反之返回true】pop3协议使用时不能判断。

	 */

	public boolean isNew() throws MessagingException {

		boolean isnew = false;//由于isnew设为false所以每次显示的都为未读

		Flags flags = ((Message) mimeMessage).getFlags();

		//System.out.println("--------flags-------" + flags);

		Flags.Flag[] flag = flags.getSystemFlags();

		//System.out.println("----flag----" + flag);

		//System.out.println("flags's length: " + flag.length);

		for (int i = 0; i < flag.length; i++) {

			//System.out.println("flag=======" + flag[i]);

			//System.out.println("-=-=-=Flags.Flag.SEEN=-=-=-="+Flags.Flag.SEEN);

			if (flag[i] == Flags.Flag.SEEN) {

				isnew = true;

				//System.out.println("seen Message.......");

				break;

			}

		}

		return isnew;

	}



	/**

	 * 判断此邮件是否包含附件

	 */



	public boolean isContainAttach(Part part) throws Exception {

		boolean attachflag = false;

		String contentType = part.getContentType();

		if (part.isMimeType("multipart/*")) {

			Multipart mp = (Multipart) part.getContent();

			for (int i = 0; i < mp.getCount(); i++) {

				BodyPart mpart = mp.getBodyPart(i);

				String disposition = mpart.getDisposition();

				if ((disposition != null)

						&& ((disposition.equals(Part.ATTACHMENT)) || (disposition

						.equals(Part.INLINE))))

					attachflag = true;

				else if (mpart.isMimeType("multipart/*")) {

					attachflag = isContainAttach((Part) mpart);

				} else {

					String contype = mpart.getContentType();

					if (contype.toLowerCase().indexOf("application") != -1)

						attachflag = true;

					if (contype.toLowerCase().indexOf("name") != -1)

						attachflag = true;

				}

			}

		} else if (part.isMimeType("message/rfc822")) {

			attachflag = isContainAttach((Part) part.getContent());

		}
		attachflag = false;
		return attachflag;


	}



	/**

	 * 【保存附件】

	 */


	public void saveAttachMent(Part part) throws Exception {

		String fileName = "";

		if (part.isMimeType("multipart/*")) {

//            Multipart mp = (Multipart) part.getContent();

//            for (int i = 0; i < mp.getCount(); i++) {
//
//                BodyPart mpart = mp.getBodyPart(i);//主体部分得到处理
//
//                String disposition = mpart.getDisposition();
//
//                if ((disposition != null)
//
//                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
//
//                                .equals(Part.INLINE)))) {//ATTACHMENT附件，INLINE嵌入
//
//                    fileName = mpart.getFileName();
//
//                    if (fileName.toLowerCase().indexOf("gb18030") != -1) {
//
//                        fileName = MimeUtility.decodeText(fileName);
//
//                    }
//
//                    saveFile(fileName, mpart.getInputStream());
//
//                } else if (mpart.isMimeType("multipart/*")) {
//
//                    saveAttachMent(mpart);
//
//                } else {
//
//                    fileName = mpart.getFileName();
//
//                    if ((fileName != null)
//
//                            && (fileName.toLowerCase().indexOf("GB18030") != -1)) {
//
//                        fileName = MimeUtility.decodeText(fileName);
//
//                        saveFile(fileName, mpart.getInputStream());
//
//                    }
//
//                }
//
//            }

		} else if (part.isMimeType("message/rfc822")) {

			saveAttachMent((Part) part.getContent());

		}

	}



	/**

	 * 【设置附件存放路径】

	 */



	public void setAttachPath(String attachpath) {

		this.saveAttachPath = attachpath;

	}



	/**

	 * 【设置日期显示格式】

	 */

	public void setDateFormat(String format) throws Exception {

		this.dateformat = format;

	}



	/**

	 * 【获得附件存放路径】

	 */

	public String getAttachPath() {

		return saveAttachPath;

	}



	/**

	 * 【真正的保存附件到指定目录里】

	 */



	private void saveFile(String fileName, InputStream in) throws Exception {

		String osName = System.getProperty("os.name");

		//System.out.println("----fileName----" + fileName);

		// String storedir = getAttachPath();

//      String separator = "";

		if (osName == null)

			osName = "";

		File storefile = new File(File.separator + "mnt" + File.separator

				+ "sdcard" + File.separator + fileName);



		storefile.createNewFile();

		//System.out.println("storefile's path: " + storefile.toString());

//       for(int i=0;storefile.exists();i++){

//       storefile = new File(storedir+separator+fileName+i);

//       }



		BufferedOutputStream bos = null;

		BufferedInputStream bis = null;

		try {

			bos = new BufferedOutputStream(new FileOutputStream(storefile));

			bis = new BufferedInputStream(in);

			int c;

			while ((c = bis.read()) != -1) {

				bos.write(c);

				bos.flush();

			}

		} catch (Exception exception) {

			exception.printStackTrace();

			throw new Exception("文件保存失败!");

		} finally {

			bos.close();

			bis.close();

		}

	}

}  

